package org.six11.olive.collabclient.server;

import java.io.PrintWriter;
import java.util.HashMap;

import org.six11.util.io.Message;
import org.six11.util.Debug;
import org.six11.util.adt.MultiState;

/**
 * This is the base class for all the StellaSketch logic handlers, which serve requests like
 * "join a room", "add some pen data" or "list possible themes for this game". Subclasses must
 * implement the aptly named 'handle' method.
 * 
 * Note that the handle function has a hibernate session and transaction that are open, so you don't
 * have to worry about that stuff.
 * 
 * @author Gabe Johnson <johnsogg@cmu.edu>
 */
public abstract class AppletMessageHandler {
  //  protected HashMap<String, AppletMessageHandler> appletMessageHandlers;
  protected MultiState state;

  public AppletMessageHandler(MultiState state) {
    this.state = state;
  }

  @SuppressWarnings("unchecked")
  protected AppletMessageHandler getMessageHandler(String name) {
    HashMap<String, AppletMessageHandler> appletMessageHandlers = (HashMap<String, AppletMessageHandler>) state.getValue("handlers");
    return appletMessageHandlers.get(name);
  }

  public abstract void handle(Message m, String sessionID, PrintWriter out);

  protected void log(String what) {
    String n = getClass().getName();
    Debug.out(">>  " + n.substring(n.lastIndexOf('.') + 1), what);
  }

  protected void bug(String what) {
    String n = getClass().getName();
    Debug.out(n.substring(n.lastIndexOf('.') + 1), what);
  }

  protected synchronized void nap(long ms) {
    try {
      wait(ms);
    } catch (InterruptedException ex) {
    }
  }

  @SuppressWarnings("unchecked")
  protected AppletMessageHandler getHandler(String type) {
    // TODO: devise some reasonable way to have symbols (rather than literals) for state keys.
    HashMap<String, AppletMessageHandler> appletMessageHandlers = (HashMap<String, AppletMessageHandler>) state
        .getValue("handlers");
    return appletMessageHandlers.get(type);
  }

  protected void error(String what) throws Exception {
    bug("Got error and throwing RuntimeException: " + what);
    throw new Exception(what);
  }
}
